﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using Small.Html.Options;

namespace Small.Html.UI
{
    public static class HtmlAutoComplete
    {
        /// <summary>
        /// 自动完成框
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="id">ID</param>
        /// <param name="format">格式</param>
        /// <returns></returns>
        public static MvcHtmlString AutoComplete(this HtmlHelper helper, string id, AutoCompleteOptions format)
        {



            return new MvcHtmlString(GenerateScript(id, format));

        }


        /// <summary>
        /// 自动完成框
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="id">ID</param>
        /// <param name="format">格式</param>
        /// <returns></returns>
        public static MvcHtmlString AutoCompleteMultipleValue(this HtmlHelper helper, string id, AutoCompleteOptions format)
        {

            
            return new MvcHtmlString(GenerateMultipleVlauesScripts(id, format));
        }


        private static string GenerateMultipleVlauesScripts(string id,  AutoCompleteOptions format)
        {

            StringBuilder builder = new StringBuilder();
            if (String.IsNullOrEmpty(format.Source))
            {
                throw new Exception("Source不能为空");
            }
            builder.Append("   $(\"#" + id + "\").bind( \"keydown\", function( event ) {    ").AppendLine();
            builder.Append("                 if ( event.keyCode === $.ui.keyCode.TAB &&  $( this ).data(\"ui-autocomplete\" ).menu.active ) ").AppendLine();
            builder.Append("                {           ").AppendLine();
            builder.Append("                       event.preventDefault();      ").AppendLine();
            builder.Append("                   }       ").AppendLine();
            builder.Append("              }).autocomplete({     ").AppendLine();
            
            builder.Append("                    source: function( request, response ) {     ").AppendLine();
            builder.Append("                      $.getJSON(\"" + format.Source + "\", { term: request.term.split(/,\\s*/).pop() },  response);  ").AppendLine();
            builder.Append("                  },        ").AppendLine();
            builder.Append(format.Delay > 0 ? ("delay:" + format.Delay + ",") : null).AppendLine();
            builder.Append("                    search: function() {    ").AppendLine();
            builder.Append("                      var term = this.value.split(/,\\s*/).pop();  ").AppendLine();
            builder.Append("                      if ( term.length < "+(format.MinLength>0?format.MinLength:2)+" ) {             ").AppendLine();
            builder.Append("                     return false;           ").AppendLine();
            builder.Append("                    }         ").AppendLine();
            builder.Append("                },         ").AppendLine();
            if (String.IsNullOrEmpty(format.FocusEvent))
            {
                builder.Append("                focus: function() {   ").AppendLine();
                builder.Append("                    return false;         ").AppendLine();
                builder.Append("                },         ").AppendLine();
            }
            else 
            {
                builder.Append("                focus: "+format.FocusEvent).AppendLine();
            }
            if (!String.IsNullOrEmpty(format.SelectEvent))
            {
                builder.Append("                select:" + format.SelectEvent).AppendLine();
            }
            else
            {
                builder.Append("                select: function( event, ui ) {    ").AppendLine();
                if (!String.IsNullOrEmpty(format.SelectedCallBack))
                {
                    builder.Append("                     if(typeof " + format.SelectedCallBack + "==\"function\"){").AppendLine();
                    builder.Append("                     " + format.SelectedCallBack + "(event,ui);     ").AppendLine();
                    builder.Append("                     };").AppendLine();
                }
                builder.Append("                     var terms = this.value.split(/,\\s*/);       ").AppendLine();
                builder.Append("                     terms.pop();          ").AppendLine();
                builder.Append("                     terms.push(ui.item.value);        ").AppendLine();
                builder.Append("                     terms.push(\"\");  ").AppendLine();
                builder.Append("                     this.value = terms.join(\", \");  ").AppendLine();
                builder.Append("                     return false;  ").AppendLine();
                builder.Append("                }  ").AppendLine();
            }
            builder.Append(string.IsNullOrEmpty(format.ChangeEvent) ? null : ("                ,change:" + format.ChangeEvent + Environment.NewLine));
            builder.Append(string.IsNullOrEmpty(format.CreateEvent) ? null : ("                ,create:" + format.ChangeEvent + Environment.NewLine));

            builder.Append(string.IsNullOrEmpty(format.OpenEvent) ? null : ("                ,open:" + format.ChangeEvent + Environment.NewLine));
            builder.Append(string.IsNullOrEmpty(format.ResponseEvent) ? null : ("                ,response:" + format.ChangeEvent + Environment.NewLine));


            builder.Append("               })");

            if (!String.IsNullOrEmpty(format.DisplayStyle))
            {
                builder.Append(GenerateDisplayStyle(format.DisplayStyle) + ";");
                builder.AppendLine();
            }
            else
            {
                builder.Append("             ;//end").AppendLine();
            }
            return builder.ToString();
          
        }

        private static String GenerateScript(string id, AutoCompleteOptions format)
        {
            if (String.IsNullOrEmpty(format.Source))
            {
                throw new Exception("Source不能为空");
            }
            StringBuilder builder = new StringBuilder();


            builder.Append("jQuery('#" + id + "').autocomplete({").AppendLine();
            builder.Append("                      source:'" + format.Source + "'");
            builder.Append(format.Delay > 0 ? ("                     ,delay:" + format.Delay + ",") : null).AppendLine();
            builder.Append(format.MinLength > 0 ? "                      ,minLength:" + format.MinLength : null).AppendLine();

            builder.Append(!String.IsNullOrEmpty(format.SelectEvent) ? "                      ,select:" + (format.SelectEvent + Environment.NewLine) : null);
            builder.Append(string.IsNullOrEmpty(format.ChangeEvent) ? null : ("                      ,change:" + format.ChangeEvent + Environment.NewLine));
            builder.Append(string.IsNullOrEmpty(format.CreateEvent) ? null : ("                      ,create:" + format.ChangeEvent + Environment.NewLine));
            builder.Append(string.IsNullOrEmpty(format.FocusEvent) ? null : ("                      ,focus:" + format.ChangeEvent + Environment.NewLine));
            builder.Append(string.IsNullOrEmpty(format.OpenEvent) ? null : ("                      ,open:" + format.ChangeEvent + Environment.NewLine));
            builder.Append(string.IsNullOrEmpty(format.ResponseEvent) ? null : ("                      ,response:" + format.ChangeEvent + Environment.NewLine));
            builder.Append(string.IsNullOrEmpty(format.ChangeEvent) ? null : ("                      ,search:" + format.ChangeEvent + Environment.NewLine));
            builder.Append("                      })");

            if (!String.IsNullOrEmpty(format.DisplayStyle))
            {
                builder.Append(GenerateDisplayStyle(format.DisplayStyle) + ";");
                builder.AppendLine();
            }
            else
            {
                builder.AppendLine("             ;//end");
            }
            return builder.ToString();
            //$( "#search" ).catcomplete({      delay: 0,      source: data    });
        }

        private static string GenerateDisplayStyle(string displayFunction)
        {


            StringBuilder builder = new StringBuilder();
            builder.Append(".data(\"ui-autocomplete\")._renderItem = function (ul, item) { ").AppendLine();
            builder.Append("                               return $(\"<li>\").append(" + displayFunction + "(item)).appendTo(ul);").AppendLine();
            builder.Append("             };//end").AppendLine();

            return builder.ToString();
        }
    }
}
